"use strict"

/**
 * 异步文件上传插件
 * 
 * @version 1.0
 */
const Upload = function (option) {
    option = option || {}
    if (typeof (option.elem) == 'undefined' || typeof (option.url) == 'undefined') {
        console.error('mon-upload hint: elem及url参数必须！');
        return null;
    }

    // 绑定的元素对象
    this.elem = document.querySelector(option.elem)
    // 上传的URL
    this.url = option.url
    // file-input的name值
    this.name = option.name || 'file'
    // 最大上传文件大小，单位kb
    this.maxSize = option.maxSize || 0
    // 允许上传的文件后缀
    this.ext = option.ext || []
    // 上传附加参数
    this.params = option.params || {}
    // 请求头
    this.headers = option.headers || {}
    // 上传成功回调
    upload_success = option.success || upload_success;
    // 上传失败的回调
    upload_error = option.error || upload_error;

    this._init();
}

Upload.prototype = {
    constructor: this,
    // 初始化
    _init: function () {
        // 清除原存在的文件上传input
        let input_file;
        if (input_file = this.elem.parentElement.querySelector("input[name='" + this.name + "']")) {
            this.elem.parentElement.removeChild(input_file);
        }
        // 创建元素
        let input = document.createElement('input')
        input.type = 'file'
        input.name = this.name
        input.style.display = 'none'
        input.id = 'mon-upload-input'
        input.setAttribute('data-url', this.url)
        input.setAttribute('data-maxSize', this.maxSize)
        input.setAttribute('data-ext', this.ext.join('|'))
        input.setAttribute('data-params', JSON.stringify(this.params))
        input.setAttribute('data-headers', JSON.stringify(this.headers))
        input.onchange = this.uploadFile;
        this.elem.parentElement.appendChild(input)
        // 绑定点击事件
        this.elem.onclick = function () {
            input.click()
        }
    },

    // 文件上传
    uploadFile: function () {
        let file;
        if (this.files) {
            file = this.files[0]
        } else {
            upload_error({ type: 'upload', msg: '当前浏览器版本太低，不支持上传插件！' })
            console.error('mon-upload hint: 当前浏览器版本太低，不支持上传插件！');
            return null;
        }


        // 验证文件大小
        let maxSize = parseInt(this.getAttribute('data-maxSize'), 10) * 1024
        if (maxSize > 0 && maxSize < file.size) {
            upload_error({ type: 'size', msg: '上传文件超过限制大小【' + maxSize + 'KB】' })
            console.error('mon-upload hint: 上传文件超过限制大小【' + maxSize + 'KB】');
            return null;
        }
        // 验证文件后缀格式
        let allowExt = this.getAttribute('data-ext') ? this.getAttribute('data-ext').split('|') : null
        if (allowExt) {
            let ext = file.name.split(".").pop();
            if (allowExt.indexOf(ext) < 0) {
                upload_error({ type: 'ext', msg: '不支持的文件格式【' + ext + '】' })
                console.error('mon-upload hint: 不支持的文件格式【' + ext + '】');
                return null;
            }
        }

        // 1.创建对象
        let xhr = new XMLHttpRequest();
        // 2.设置请求行(get请求数据写在url后面)
        let url = this.getAttribute('data-url');
        xhr.open('post', url);
        // 3.设置请求头(get请求可以省略,post不发送数据也可以省略)
        let headersJson = this.getAttribute('data-headers')
        let headers = JSON.parse(headersJson)
        for (let key in headers) {
            xhr.setRequestHeader(key, headers[key]);
        }
        // 4.注册回调函数
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    upload_success(JSON.parse(xhr.responseText));
                } else {
                    upload_error(xhr.responseText);
                }
            }
        };
        // XHR2.0新增 上传进度监控
        xhr.upload.onprogress = function (event) {
            // console.log(event);
        }
        // 处理发送数据
        let data = new FormData()
        let params = this.getAttribute('data-params');
        params = JSON.parse(params)
        for (let key in params) {
            let value = params[key]
            // todo 暂时不支持函数，待后续优化
            // if (typeof value == 'function') {
            //     value = value.apply(this, file)
            // }
            data.append(key, value)
        }
        let name = this.getAttribute('name');
        data.append(name, file)
        // 6.请求主体发送
        xhr.send(data);
    }
}

// 默认成功回调
let upload_success = function (data) {
    console.log(data)
}

// 默认失败回调
let upload_error = function (data) {
    console.log(data)
}

export default Upload